try {
	Type.registerNamespace('NCMMBarcodeParseUtil');
	//元数据
	var metadataStrategy = "1";
	//条码字典
	var barcodedicStrategy = "2";
	//固定值
	var fixvalueStrategy = "4";
	//标志位
	var barflagStrategy = "6";
	//左补位
	var complementleft = 1;
	//右补位
	var complementright = 2;

	//解析单据条码
	NCMMBarcodeParseUtil.parseBillBar = function(billbarcode) {
		var json = {
			"billcode": "",
			"rowno": ""
		}
		if(NCMMPubUtil.isEmpty(billbarcode)) {
			return json;
		};
		if(billbarcode.length < 20) {
			return json;
		}
		//开始按照单据号位置进行解析
		var billcode = billbarcode.substring(0, 20);
		var rowno = billbarcode.substring(20, billbarcode.length);
		json.billcode = billcode;
		json.rowno = rowno;
		return json;
	};
	//解析物料条码
	NCMMBarcodeParseUtil.parseMaterialBar = function(marbarcode) {
		//定义物料解析后返回json,
		//pk_material:物料主键,code：物料编码,vprodbatchcode:生产批次号,vbatchcode:库存批次,vserialcode:序列号,failmsg:异常信息
		var pk_material = MarCodeResultVO.PKMATERIAL.name;
		var code = MarCodeResultVO.CODE.name;
		var vprodbatchcode = MarCodeResultVO.VPRODBATCHCODE.name;
		var vbatchcode = MarCodeResultVO.VBATCHCODE.name;
		var pk_batch = MarCodeResultVO.PKBATCH.name;
		var vserialcode = MarCodeResultVO.VSERIALCODE.name;
		var failmsg = MarCodeResultVO.FAILMSG.name;
		var materialbarcode = "materialbarcode";
		var materialspec = "materialspec";
		var materialtype = "materialtype";
		var materialmnecode = "materialmnecode";
		var returnjson = {
			pk_material: "",
			code: "",
			vprodbatchcode: "",
			vbatchcode: "",
			pk_batch: "",
			vserialcode: "",
			materialbarcode: "",
			materialspec: "",
			materialtype: "",
			materialmnecode: "",
			failmsg: ""
		};
		if(NCMMPubUtil.isEmpty(marbarcode)) {
			returnjson.failmsg = "解析物料条码不能为空！";
			return returnjson;
		};
		if(!NCMMPubUtil.isTableExist(BarCodeRuleVO)) {
			returnjson.failmsg = "本地【条码规则表】不存在，请检查!";
			return returnjson;
		}
		//根据条码长度和类型和集团从app_bcbd_barcoderule查询出符合条件的条码规则
		var wheresql = " where length_h='" + marbarcode.length + "' and bartypename in('物料码','单件条码')";
		var ruleheads = NCMMPubUtil.queryVONoCallback(BarCodeRuleVO, wheresql);
		if(NCMMPubUtil.isEmpty(ruleheads) || ruleheads == "[]") {
			returnjson.failmsg = "根据条码【" + marbarcode + "】的长度没有匹配到任何物料码或单件条码规则！";
			return returnjson;
		}
		ruleheads = $stringToJSON(ruleheads);
		//当匹配到多个物料条码规则时则不进行解析
		if(ruleheads.length != 1) {
			ruleheads = NCMMBarcodeParseUtil.filterRuleByFixAndBarFlag(ruleheads, marbarcode);
			if(NCMMPubUtil.isEmpty(ruleheads) || ruleheads == "[]") {
				returnjson.failmsg = "根据条码【" + marbarcode + "】的长度和固定值或标志位没有匹配到任何物料码或单件条码规则！";
				return returnjson;
			} else if(ruleheads.length != 1) {
				returnjson.failmsg = "根据条码【" + marbarcode + "】的长度和固定值或标志位匹配到多个物料码或单件条码规则，不予解析！";
				return returnjson;
			}
		}
		//匹配到唯一的物料条码规则则进行解析
		var headrule = ruleheads[0];
		var pk_barcoderule = headrule.pk_barcoderule;
		if(!NCMMPubUtil.isTableExist(BarCodeRuleBodyVO)) {
			returnjson.failmsg = "本地【条码规则明细表】不存在，请检查!";
			return returnjson;
		}
		//查询条码规则表体vo并按照起始位置进行排序
		var subwheresql = " where pk_barcoderule ='" + pk_barcoderule + "'";
		var ruleItems = NCMMPubUtil.queryVONoCallback(BarCodeRuleBodyVO, subwheresql);
		if(NCMMPubUtil.isEmpty(ruleItems) || ruleItems == "[]") {
			returnjson.failmsg = "匹配到物料码或单件条码规则明细为空，无法解析！";
			return returnjson;
		}
		ruleItems = $stringToJSON(ruleItems);
		if(ruleItems.length == 0) {
			returnjson.failmsg = "匹配到物料码或单件条码规则明细为空，无法解析！";
			return returnjson;
		}
		for(var i = 0; i < ruleItems.length; i++) {
			var strategy = ruleItems[i].accessstrategy
			if(fixvalueStrategy == strategy || barflagStrategy == strategy)
				continue;

			var startpos = ruleItems[i].startpos;
			var length = ruleItems[i].length;
			//获取当前条码对象对应物料码部分
			var sectioncode = marbarcode.substr(startpos - 1, length);
			//物料码部分去掉前后填充符
			sectioncode = NCMMBarcodeParseUtil.removefillcode(headrule.fillcode, headrule.complement, sectioncode);
			//如果是条码字典，则根据code和rultItem[i]条码字典主键查询条码字段子表，从子表中拿出业务对象主键和编码即可
			if(barcodedicStrategy == strategy) {
				//条码对象属性路径
				var mdattrid = ruleItems[i].appobjattrmdattrid;
				NCMMBarcodeParseUtil.processbardict(ruleItems[i], mdattrid, returnjson, sectioncode);
			} else if(metadataStrategy == strategy) {
				//条码对象属性值
				var attrvalue = ruleItems[i].appobjattrvalue;
				NCMMBarcodeParseUtil.processmetadata(attrvalue, returnjson, sectioncode)
			}
		}
		//根据物料编码获取物料主键
		returnjson = NCMMBarcodeParseUtil.getMarPKByCode(returnjson);
		if(returnjson.failmsg != "") {
			return returnjson;
		}
		//当物料编码为空时，则通过物料别的属性进行查询
		returnjson = NCMMBarcodeParseUtil.getMarByOtherCondition(returnjson);
		if(returnjson.failmsg != "") {
			return returnjson;
		}
		//当物料pk和库存批次号都不为空时，库存批次pk为空再查询库存批次pk
		returnjson = NCMMBarcodeParseUtil.getbatchPKByMarAndBatchcode(returnjson);
		return returnjson;
	};
	//处理取值策略为条码字典的情况
	NCMMBarcodeParseUtil.processbardict = function(ruleItem, mdattrid, returnjson, sectioncode) {
		if(!NCMMPubUtil.isTableExist(BarCodeDictBodyVO)) {
			returnjson.failmsg = "本地【条码字典明细表】不存在，请检查!";
			return;
		}
		var conditon = " where barcode='" + sectioncode + "' and pk_bcdict='" + ruleItem.pk_bardict + "'"
		var results = NCMMPubUtil.queryVONoCallback(BarCodeDictBodyVO, conditon);
		if(NCMMPubUtil.isEmpty(results) || results == "[]") {
			returnjson.failmsg = "起始位置为" + ruleItem.startpos + "的条码规则明细根据条码和条码字典，没有匹配到任何条码字典明细！";
			return;
		}
		results = $stringToJSON(results);
		if(results.length == 0) {
			returnjson.failmsg = "起始位置为" + ruleItem.startpos + "的条码规则明细根据条码和条码字典，没有匹配到任何条码字典明细！";
			return;
		}
		//根据业务对象属性元数据路径判断
		switch(mdattrid) {
			case "vprodbatchcode":
				returnjson.vprodbatchcode = results[0].busiobjcode;
				break;
			case "vbatchcode":
				returnjson.vbatchcode = results[0].busiobjcode;
				break;
			case "vserialcode":
				returnjson.vserialcode = results[0].busiobjcode;
				break;
			case "cmaterial":
				returnjson.code = results[0].busiobjcode;
				returnjson.pk_material = results[0].busiobjectid;
				break;
		}
	};
	//处理取值策略为元数据的情况
	NCMMBarcodeParseUtil.processmetadata = function(attrvalue, returnjson, sectioncode) {
		//根据业务对象属性值判断
		switch(attrvalue) {
			case "vprodbatchcode":
				returnjson.vprodbatchcode = sectioncode;
				break;
			case "vbatchcode":
				returnjson.vbatchcode = sectioncode;
				break;
			case "vserialcode":
				returnjson.vserialcode = sectioncode;
				break;
			case "cmaterial.code":
				returnjson.code = sectioncode;
				break;
			case "cmaterial.materialbarcode":
				returnjson.materialbarcode = sectioncode;
				break;
			case "cmaterial.materialspec":
				returnjson.materialspec = sectioncode;
				break;
			case "cmaterial.materialtype":
				returnjson.materialtype = sectioncode;
				break;
			case "cmaterial.materialmnecode":
				returnjson.materialmnecode = sectioncode;
				break;
		}
	};
	//去掉左右填充符号
	NCMMBarcodeParseUtil.removefillcode = function(fillcode, complement, sectioncode) {
		if(complement == complementleft) {
			while(sectioncode.charAt(0) == fillcode) {
				sectioncode = sectioncode.substring(1, sectioncode.length);
			}

		} else if(complement == complementright) {
			while(sectioncode.charAt(sectioncode.length - 1) == fillcode) {
				sectioncode = sectioncode.substring(0, sectioncode.length - 1);
			}
		}
		return sectioncode;
	};
	//根据固定值或者标志位过滤条码规则
	NCMMBarcodeParseUtil.filterRuleByFixAndBarFlag = function(ruleheads, marbarcode) {
		var returnRules = [];
		if(NCMMPubUtil.isEmpty(ruleheads) || ruleheads == "[]") {
			return returnRules;
		}
		for(var i = 0; i < ruleheads.length; i++) {
			var flag = false;
			var subwheresql = " where pk_barcoderule ='" + ruleheads[i].pk_barcoderule + "'";
			var ruleItems = NCMMPubUtil.queryVONoCallback(BarCodeRuleBodyVO, subwheresql);
			if(NCMMPubUtil.isEmpty(ruleItems) || ruleItems == "[]") {
				continue;
			}
			ruleItems = $stringToJSON(ruleItems);
			for(var j = 0; j < ruleItems.length; j++) {
				var strategy = ruleItems[j].accessstrategy
				if(fixvalueStrategy == strategy || barflagStrategy == strategy) {
					var startpos = ruleItems[j].startpos;
					var length = ruleItems[j].length;
					//获取当前条码对象对应物料码部分
					var matchcode = marbarcode.substr(startpos - 1, length);
					var attrvalue = ruleItems[j].appobjattrvalue;
					if(matchcode != attrvalue) {
						flag = true;
						break;
					}
				}
			}
			if(flag == false) {
				returnRules.push(ruleheads[i]);
			}
		}
		return returnRules;
	};
	//当条码规则中没有物料编码信息时可以通过别的属性，例如，型号、规格等获取物料信息
	NCMMBarcodeParseUtil.getMarByOtherCondition = function(returnjson) {
		//当物料编码为空时，则通过物料别的属性进行查询
		if(returnjson.code != "") {
			return returnjson;
		}
		var condition = " where ";
		var newcondition = "";
		if(returnjson.materialbarcode != "") {
			newcondition = condition.concat(MaterialVO.MATERIALBARCODE.name + "='" + returnjson.materialbarcode + "' and ");
		}
		if(returnjson.materialspec != "") {
			newcondition = condition.concat(MaterialVO.MATERIALSPEC.name + "='" + returnjson.materialspec + "' and ");
		}
		if(returnjson.materialtype != "") {
			newcondition = condition.concat(MaterialVO.MATERIALTYPE.name + "='" + returnjson.materialtype + "' and ");
		}
		if(returnjson.materialmnecode != "") {
			newcondition = condition.concat(MaterialVO.MATERIALMNECODE.name + "='" + returnjson.materialmnecode + "' and ");
		}
		if(newcondition == null || newcondition == "" || newcondition == condition) {
			return returnjson;
		}
		if(!NCMMPubUtil.isTableExist(MaterialVO)) {
			returnjson.failmsg = "本地【物料表】不存在，请检查!";
			return returnjson;
		}
		var index = newcondition.lastIndexOf("and");
		newconditon = newcondition.substring(0, index);
		var materialvo = NCMMPubUtil.queryVONoCallback(MaterialVO, newconditon);
		if(NCMMPubUtil.isEmpty(materialvo) || materialvo == "[]") {
			returnjson.failmsg = "根据物料的其它属性没有匹配到任何物料!";
			return returnjson;
		}
		var marjson = $stringToJSON(materialvo);
		if(marjson.length == 1) {
			returnjson.code = marjson[0].code;
			returnjson.pk_material = marjson[0].pk_material;
		} else {
			returnjson.failmsg = "根据物料的其它属性匹配到多个物料!";
		}
		return returnjson;
	};
	//当物料pk和库存批次号都不为空时，库存批次pk为空再查询库存批次pk
	NCMMBarcodeParseUtil.getbatchPKByMarAndBatchcode = function(returnjson) {
		if(NCMMPubUtil.isEmpty(returnjson.pk_material) || NCMMPubUtil.isEmpty(returnjson.vbatchcode) || NCMMPubUtil.isNotEmpty(returnjson.pk_batch)) {
			return returnjson;
		}
		if(!NCMMPubUtil.isTableExist(BatchcodeVO)) {
			returnjson.failmsg = "本地【库存批次表】不存在，请检查!";
			return returnjson;
		}
		var conditon = " where vbatchcode='" + returnjson.vbatchcode + "' and cmaterialvid='" + returnjson.pk_material + "'";
		var batchcodevos = NCMMPubUtil.queryVONoCallback(BatchcodeVO, conditon);
		if(NCMMPubUtil.isEmpty(batchcodevos) || batchcodevos == "[]") {
			returnjson.failmsg = "根据物料和批次号没有匹配到任何库存批次，无法返回批次！";
			return returnjson;
		}
		batchcodevos = $stringToJSON(batchcodevos);
		if(batchcodevos.length == 1) {
			returnjson.pk_batch = batchcodevos[0].pk_batchcode;
		} else if(batchcodevos.length == 0) {
			returnjson.failmsg = "根据物料和批次号没有匹配到任何库存批次，无法返回批次！";
		} else {
			returnjson.failmsg = "根据物料和批次号匹配到多个库存批次，无法返回批次！";
		}
		return returnjson;
	};
	//如果物料编码不为空，则根据物料编码获取物料pk
	NCMMBarcodeParseUtil.getMarPKByCode = function(returnjson) {
		if(returnjson.code == "" || returnjson.pk_material != "") {
			return returnjson;
		}
		if(!NCMMPubUtil.isTableExist(MaterialVO)) {
			returnjson.failmsg = "本地【物料表】不存在，请检查!";
			return returnjson;
		}
		//这里暂时这样处理多版本问题，可能会有问题，以后讨论了方案再改进
		var conditon = " where code='" + returnjson.code + "' order by version desc limit 1";
		var results = NCMMPubUtil.queryVONoCallback(MaterialVO, conditon);
		if(NCMMPubUtil.isEmpty(results) || results == "[]") {
			returnjson.failmsg = "根据物料编码没有匹配到任何物料，无法返回物料！";
			return returnjson;
		}
		results = $stringToJSON(results);
		if(results.length == 1) {
			returnjson.pk_material = results[0].pk_material;
		} else if(results.length == 0) {
			returnjson.failmsg = "根据物料编码没有匹配到任何物料，无法返回物料！";
		} else {
			returnjson.failmsg = "根据物料编码最新版本匹配到多条物料记录，无法返回物料！";
		}
		return returnjson;
	};

} catch(e) {
	$e(e);
}